home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / QuickDraw / RotateString / RotateString Lib ƒ / Rotate code / RotateString.c next >
Encoding:
C/C++ Source or Header  |  1994-02-09  |  4.1 KB  |  140 lines  |  [TEXT/KAHL]

  1. /*
  2.     RotateString sample code
  3.     By Randy Theland and Brigham Stevens
  4.     Apple Computer Developer Technical Support
  5.     
  6.     This function will return a BitMap that contains the
  7.     text passed rotated 90°
  8.     
  9.     The font characteristics are copied from
  10.     the current port before creating the BitMap.
  11.     
  12. */
  13.  
  14. #include "RotateString.h"
  15.  
  16. /*
  17.     In pascal this is:
  18.  
  19.  function RotateString (str: Str255; var destMap: BitMap, direction : integer): OSErr;
  20.  
  21. */
  22.  
  23.  
  24. pascal OSErr RotateString( Str255 str, BitMap *destMap, short direction)
  25. {
  26.     GrafPort    srcPort;
  27.     BitMap        srcMap;
  28.     char        *srcPtr, *destPtr;
  29.     FontInfo    f;
  30.     short        heightBits, heightBytes;
  31.     short        width, widthBytes;
  32.     short        rotateWidth;
  33.     short        rotateHeight;
  34.     short        row, column;
  35.     short        texFont,texFace,texMode,texSize;    
  36.     short        err;
  37.     GrafPtr        savePort;
  38.     
  39.     GetPort(&savePort);
  40.     
  41.     texFont = thePort->txFont;
  42.     texFace = thePort->txFace;
  43.     texMode = thePort->txMode;
  44.     texSize = thePort->txSize;
  45.     
  46.     OpenPort( &srcPort);
  47.     SetPort(&srcPort);
  48.     
  49.     TextFont(texFont);    
  50.     TextFace(texFace);    
  51.     TextMode(texMode);    
  52.     TextSize(texSize);
  53.     GetFontInfo( &f);
  54.     
  55.     heightBits = f.ascent + f.descent + f.leading;
  56.     heightBytes = ((heightBits + 7) & 0x7FF8) >> 3;
  57.     width = StringWidth( str);
  58.     widthBytes = ((width + 7) & 0x7FF8) >> 3;
  59.  
  60.     rotateWidth = heightBytes;
  61.     rotateHeight = widthBytes << 3;
  62.     
  63.     srcPort.portBits.baseAddr = NewPtrClear( widthBytes * heightBits);
  64.     if(err = MemError()) return err;
  65.  
  66.     srcPort.portBits.rowBytes = widthBytes;
  67.     SetRect( &srcPort.portBits.bounds, 0, 0, width, heightBits);
  68.  
  69.     destMap->baseAddr = NewPtrClear( rotateWidth * rotateHeight);
  70.     if(err = MemError()) {
  71.         DisposePtr(srcPort.portBits.baseAddr);
  72.         return err;
  73.     }
  74.     
  75.     destMap->rowBytes = rotateWidth;
  76.     SetRect( &destMap->bounds, 0, 0, rotateWidth * 8, rotateHeight);
  77.     
  78.     RectRgn(srcPort.visRgn,&srcPort.portBits.bounds);
  79.     MoveTo( 0, f.ascent);  // change 2.0.1 <CKH> was heightBits
  80.     DrawString( str);
  81.  
  82.     
  83.     /*****************************************/
  84.     /*  Rotate Algorithm                     */
  85.     /*****************************************/
  86.  
  87.     srcPtr = srcPort.portBits.baseAddr;        // Start at the Top,Left
  88.     
  89.     if(direction == counterClockWise)        // Start at the Bottom,Left
  90.         destPtr = destMap->baseAddr + ((rotateHeight-1) * rotateWidth);
  91.     else                                    // Start at the Top,Left
  92.         destPtr = destMap->baseAddr;
  93.                                             
  94.     for( column = 0; column < width; column++)        /* width is in pixels */
  95.     {
  96.         for( row = 0; row < heightBits; row++)        /* height in pixels, too */
  97.         {
  98.         
  99.             if(direction == counterClockWise) {
  100.                 /* We are rotating left ( counter clock-wise) thus */
  101.                 /*  as we search across the top of the horizontal pixel bit map,    */
  102.                 /*    we write down the right edge of the vertical pixel bit map */
  103.  
  104.                 if( *(srcPtr                        /* Begin with the upper left corner */ 
  105.                         + (row*widthBytes)             /* Move down a row */
  106.                         + (column >> 3))            /* Go to the first even byte */
  107.                         & (0x80>>(column & 7)) )    /* calculate a shifted bit position based on the column */
  108.                     {
  109.                         *(destPtr                     /* Begin in the lower left corner */
  110.                             - (column*rotateWidth)     /* Subtract, move up for each row */
  111.                             + (row >> 3))             /* Calculate a bit position for the column */
  112.                             |= (0x80>>(row & 7));    /* Set a bit based on the column */
  113.                     }
  114.             } else {    /* clockWise */
  115.                 /*  We are rotating right (clock-wise) thus */
  116.                 /*  as we search across the top of the horizontal pixel bit map,    */
  117.                 /*    we write down the left edge of the vertical pixel bit map */
  118.                 
  119.                 if( *(srcPtr                        /* Begin with the upper left corner */ 
  120.                         + (row*widthBytes)             /* Move down a row */
  121.                         + (column >> 3))            /* Go to the first even byte */
  122.                         & (0x80>>(column & 7)) )    /* calculate a shifted bit position based on the column */
  123.                     {
  124.                         *(destPtr                     /* Begin in the lower left corner */
  125.                         + (column*rotateWidth) /* Add, move down for each row */
  126.                         - (row >> 3))             /* Calculate a bit position for the column */
  127.                         |= (0x01<<(row & 7));    /* Set a bit based on the column */
  128.                     }
  129.             }
  130.         }
  131.     }
  132.     
  133.     /* clean up the used source BitMap, and restore the ports properly */    
  134.     DisposePtr(srcPort.portBits.baseAddr);
  135.     ClosePort(&srcPort);
  136.     SetPort(savePort);
  137.     
  138.     return noErr;
  139. }
  140.